home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oh!X 2001 Spring
/
Oh!X 2001 Spring Special CD-ROM (Japan).7z
/
Oh!X 2001 Spring Special CD-ROM (Japan) (Track 1).bin
/
VC
/
layered3
/
layered3.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2000-08-11
|
9KB
|
293 lines
// layered3.cpp : アプリケーション用のエントリ ポイントの定義
//
#include "stdafx.h"
#include "layeredwnd.h"
#define APPNAME "LayeredWindow3"
static char szAppName[] = APPNAME;
static char szTitle[] = APPNAME;
#define MM_QUIT WM_USER+1
LayeredWnd *playeredWnd;
HINSTANCE hInst; // USER32.DLL のインスタンスハンドル
// SetLayeredWindowAttributes のアドレス
BOOL (WINAPI *_SetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
// UpdateLayeredWindow のアドレス
BOOL (WINAPI *_UpdateLayeredWindow)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
// TODO: この位置にコードを記述してください。
OSVERSIONINFO versioninfo;
versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx( &versioninfo );
if( versioninfo.dwMajorVersion<5 ){
MessageBox( NULL, "このバージョンのWindowsでは動作しません。", "LayeredWindow",MB_OK|MB_ICONHAND );
return FALSE;
}
if( !InitInstance( hInstance ) ){
MessageBox( NULL, "アプリケーションの初期化に失敗しました。", "LayeredWindow", MB_OK|MB_ICONHAND );
return FALSE;
}
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) ){
TranslateMessage( &msg ); // Translates virtual key codes.
DispatchMessage( &msg ); // Dispatches message to window.
}
ExitInstance();
return msg.wParam; // Returns the value from PostQuitMessage.
}
BOOL InitInstance( HINSTANCE hInstance )
{
// SetLayeredWindowAttributes のエクスポートアドレスの取得
hInst = LoadLibrary( "USER32.DLL" );
if( hInst ){
_SetLayeredWindowAttributes = (BOOL(WINAPI*)(HWND,COLORREF,BYTE,DWORD))
GetProcAddress( hInst, "SetLayeredWindowAttributes" );
_UpdateLayeredWindow = (BOOL(WINAPI*)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD))
GetProcAddress( hInst, "UpdateLayeredWindow" );
}
if( _SetLayeredWindowAttributes==NULL || _UpdateLayeredWindow==NULL ) return FALSE;
playeredWnd = new LayeredWnd( hInstance );
HWND hWnd = playeredWnd->Create();
return hWnd?TRUE:FALSE;
}
void ExitInstance()
{
if( playeredWnd ) delete playeredWnd;
if( hInst ) FreeLibrary( hInst );
}
LONG APIENTRY MainWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam )
{
if( message==WM_NCCREATE ){
CREATESTRUCT *pcs = (CREATESTRUCT*)lParam;
SetWindowLong( hWnd, GWL_USERDATA, (LONG)pcs->lpCreateParams );
}
LayeredWnd *pWnd = (LayeredWnd*)GetWindowLong( hWnd, GWL_USERDATA );
if( pWnd==NULL ){
return DefWindowProc( hWnd, message, wParam, lParam );
} else {
return pWnd->WndProc( hWnd, message, wParam, lParam );
}
return 0;
}
//////////////////////////////////////////////////////////////////////
// LayeredWnd クラス
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// 構築/消滅
//////////////////////////////////////////////////////////////////////
LayeredWnd::LayeredWnd( HINSTANCE hInstance )
{
WNDCLASSEX wc;
wc.cbSize = sizeof( WNDCLASSEX );
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;
wc.hIconSm = NULL;
RegisterClassEx( &wc );
m_hInstance = hInstance;
m_hMenu = CreatePopupMenu();
MENUITEMINFO mi;
mi.cbSize = sizeof(MENUITEMINFO);
mi.fMask = MIIM_ID|MIIM_TYPE;
mi.fType = MFT_STRING;
mi.wID = MM_QUIT;
mi.dwTypeData = "終了";
mi.cch = strlen( mi.dwTypeData );
InsertMenuItem( m_hMenu, 0, TRUE, &mi );
HBITMAP hBitmap = LoadBitmap( m_hInstance, MAKEINTRESOURCE(IDB_RGB) );
HBITMAP hAlpha = LoadBitmap( m_hInstance, MAKEINTRESOURCE(IDB_ALPHA) );
m_hBitmap = CreateAlphaContainedBitmap( hBitmap, hAlpha );
HDC hDC = GetDC( NULL );
m_hDC = CreateCompatibleDC( hDC );
ReleaseDC( NULL, hDC );
SelectObject( m_hDC, m_hBitmap );
m_nWidth = 200;
m_nHeight = 90;
m_nFrame = 0;
}
// Alpha付きのビットマップを作成
// 入力 hBitmap カラービットマップ
// hAlpha アルファビットマップ(R成分)
// 出力 32ビットビットマップ
HBITMAP LayeredWnd::CreateAlphaContainedBitmap( HBITMAP hBitmap, HBITMAP hAlpha )
{
BITMAPINFOHEADER *pbmih1 = (BITMAPINFOHEADER*)GlobalAlloc( GPTR, sizeof(BITMAPINFOHEADER) );
memset( pbmih1, 0, sizeof(BITMAPINFOHEADER) );
pbmih1->biSize = sizeof(BITMAPINFOHEADER);
HDC hDC = GetDC( NULL );
GetDIBits( hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)pbmih1, DIB_RGB_COLORS );
pbmih1->biBitCount = 24;
pbmih1->biCompression = BI_RGB;
pbmih1->biXPelsPerMeter = pbmih1->biYPelsPerMeter = 0;
pbmih1->biClrUsed = pbmih1->biClrImportant = 0;
BITMAPINFOHEADER *pbmih2 = (BITMAPINFOHEADER*)GlobalAlloc( GPTR, sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256 );
memset( pbmih2, 0, sizeof(BITMAPINFOHEADER) );
pbmih2->biSize = sizeof(BITMAPINFOHEADER);
GetDIBits( hDC, hAlpha, 0, 0, NULL, (BITMAPINFO*)pbmih2, DIB_RGB_COLORS );
pbmih2->biBitCount = 8;
pbmih2->biCompression = BI_RGB;
pbmih2->biXPelsPerMeter = pbmih2->biYPelsPerMeter = 0;
pbmih2->biClrUsed = pbmih2->biClrImportant = 256;
RGBQUAD *rgb = (RGBQUAD*)(pbmih2+1);
BITMAPINFOHEADER *pbmih3 = (BITMAPINFOHEADER*)GlobalAlloc( GPTR, sizeof(BITMAPINFOHEADER) );
memset( pbmih3, 0, sizeof(BITMAPINFOHEADER) );
pbmih3->biSize = sizeof(BITMAPINFOHEADER);
pbmih3->biWidth = pbmih1->biWidth;
pbmih3->biHeight = pbmih1->biHeight;
pbmih3->biPlanes = 1;
pbmih3->biBitCount = 32;
pbmih3->biCompression = BI_RGB;
pbmih3->biSizeImage = 0;
pbmih3->biXPelsPerMeter = 0;
pbmih3->biYPelsPerMeter = 0;
pbmih3->biClrUsed = 0;
pbmih3->biClrImportant = 0;
int line1 = (pbmih1->biWidth*3+3)/4*4;
LPBYTE lpvBits1 = (LPBYTE)GlobalAlloc( GPTR, line1*pbmih1->biHeight );
GetDIBits( hDC, hBitmap, 0, pbmih1->biHeight, lpvBits1, (BITMAPINFO*)pbmih1, DIB_RGB_COLORS );
int line2 = (pbmih2->biWidth+3)/4*4;
LPBYTE lpvBits2 = (LPBYTE)GlobalAlloc( GPTR, line2*pbmih2->biHeight );
GetDIBits( hDC, hAlpha, 0, pbmih2->biHeight, lpvBits2, (BITMAPINFO*)pbmih2, DIB_RGB_COLORS );
LPBYTE pvBits;
HBITMAP hNewBitmap = CreateDIBSection( hDC, (BITMAPINFO*)pbmih3, DIB_RGB_COLORS, (void**)&pvBits, NULL, 0 );
LPBYTE p1 = lpvBits1, p2 = lpvBits2, p3 = pvBits;
for( int y=0; y<pbmih3->biHeight; y++ ){
for( int x=0; x<pbmih3->biWidth; x++ ){
*(p3++) = *(p1++);
*(p3++) = *(p1++);
*(p3++) = *(p1++);
*(p3++) = rgb[*(p2++)].rgbRed;
}
p1 += line1-pbmih3->biWidth*3;
p2 += line2-pbmih3->biWidth;
}
ReleaseDC( NULL, hDC );
GlobalFree( lpvBits1 );
GlobalFree( lpvBits2 );
GlobalFree( pbmih1 );
GlobalFree( pbmih2 );
GlobalFree( pbmih3 );
return hNewBitmap;
}
LayeredWnd::~LayeredWnd()
{
DeleteDC( m_hDC );
DeleteObject( m_hBitmap );
DestroyMenu( m_hMenu );
}
HWND LayeredWnd::Create()
{
CREATESTRUCT cs;
cs.lpCreateParams = this;
cs.hInstance = m_hInstance;
cs.hMenu = NULL;
cs.hwndParent = NULL;
cs.cy = m_nHeight;
cs.cx = m_nWidth;
cs.y = CW_USEDEFAULT;
cs.x = CW_USEDEFAULT;
cs.style = WS_POPUP|WS_VISIBLE;
cs.lpszName = szTitle;
cs.lpszClass = szAppName;
cs.dwExStyle = WS_EX_LAYERED; // レイヤードウィンドウ
m_hWnd = CreateWindowEx( cs.dwExStyle, cs.lpszClass, cs.lpszName, cs.style,
cs.x, cs.y, cs.cx, cs.cy, cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams );
return m_hWnd;
}
LRESULT LayeredWnd::WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message ){
case WM_CREATE:
OnCreate( hWnd );
return 0;
case WM_DESTROY:
OnDestroy( hWnd );
PostQuitMessage( 0 );
return 0;
case WM_NCHITTEST:
return OnNcHitTest( LOWORD(lParam), HIWORD(lParam) );
case WM_NCRBUTTONDOWN:
OnNcRButtonDown( wParam, MAKEPOINTS(lParam) );
return 0;
case WM_COMMAND:
switch( LOWORD(wParam) ){
case MM_QUIT:
DestroyWindow( m_hWnd );
return 0;
}
break;
case WM_TIMER:
m_nFrame = Animate( hWnd, m_nFrame );
return 0;
}
return DefWindowProc( hWnd, message, wParam, lParam );
}
void LayeredWnd::OnCreate( HWND hWnd )
{
m_nFrame = Animate( hWnd, m_nFrame );
SetTimer( hWnd, 1, 100, NULL );
}
int LayeredWnd::Animate( HWND hWnd, int frm )
{
POINT point = { (frm%5)*m_nWidth, (frm/5)*m_nHeight };
SIZE size = { m_nWidth, m_nHeight };
BLENDFUNCTION blend;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
_UpdateLayeredWindow( hWnd, NULL, NULL, &size, m_hDC, &point, 0, &blend, ULW_ALPHA );
return (frm+1)%10;
}
void LayeredWnd::OnDestroy( HWND hWnd )
{
KillTimer( hWnd, 1 );
}
int LayeredWnd::OnNcHitTest( int xPos, int yPos )
{
return HTCAPTION;
}
void LayeredWnd::OnNcRButtonDown( int nHittest, POINTS pts )
{
TrackPopupMenu( m_hMenu, TPM_LEFTALIGN|TPM_TOPALIGN, pts.x, pts.y, 0, m_hWnd, NULL );
}